package com.aqie.easy.doublePointer;

import java.util.Arrays;
import java.util.HashSet;

/**
 * 345 反转字符串中元音字母 aeiou todo
 */
public class ReverseVowels {
    /**
     * 1, 19ms
     */
    private final static HashSet<Character> set = new HashSet<>(Arrays.asList('a', 'o', 'e', 'i', 'u', 'A', 'O', 'E', 'I', 'U'));

    public String reverseVowels(String s) {
        int i = 0, j = s.length() - 1;
        char[] result = new char[s.length()];
        while (i <= j) {
            char ci = s.charAt(i);
            char cj = s.charAt(j);
            if (!set.contains(ci)) {
                result[i++] = ci;
            } else if (!set.contains(cj)) {
                result[j--] = cj;
            } else {
                result[i++] = cj;
                result[j--] = ci;
            }
        }
        return new String(result);
    }

    /**
     * 2， 双指针从两端遍历 11ms
     *
     * @param s
     * @return
     */
    public String reverseVowels2(String s) {
        if (s.length() == 0 || s.length() == 1) return s;
        int left = 0;
        int right = s.length() - 1;
        //由于String无法直接更改字母，故先转换为char数组
        char[] chars = s.toCharArray();
        while (left < right) {
            //从左侧找元音字母
            while (!match(chars[left])) {
                left++;
                if (left == s.length()) return s;
            }
            //从右侧找元音字母
            while (!match(chars[right])) {
                right--;
            }

            //加上判断条件，以免反转两次
            if (left < right) {
                char c = chars[left];
                chars[left] = chars[right];
                chars[right] = c;
            } else break;

            //此处反转之后需要有自增自减操作，否则会无限反转在这两位上
            left++;
            right--;
            if (left == s.length() || right == -1) break;
        }
        //返回反转后的字符串
        return new String(chars);
    }

    private static boolean match(char c) {
        boolean flag = false;
        char[] chars = {'a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'};
        for (char val : chars) {
            if (val == c) flag = true;
        }
        return flag;
    }
}
